package com.yueke.gemini.qrcodeutil;


import com.google.zxing.*;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.OutputStream;
import java.net.URL;
import java.util.Hashtable;
import java.util.Random;

/**
 * 说明：1.生成二维码工具类(可带中间LOGO)
 * 		 2.解析二维码
 * 	create by admin  2016
 */
public class QRCodeUtil {

	    private static final String CHARSET = "utf-8";
	    private static final String FORMAT_NAME = "JPG";
	    // 二维码尺寸
	    private static final int QRCODE_SIZE = 430; //default:430
	    // LOGO宽度
	    private static final int WIDTH = 120; //default:80
	    // LOGO高度
	    private static final int HEIGHT = 120;

		/**
		 * 生成二维码
		 * @param content 内容
		 * @param imgPath  LOGO图片地址
		 * @param needCompress 是否压缩
		 * @return
		 * @throws Exception
		 */
	    private static BufferedImage createImage(String content, String imgPath, boolean needCompress) throws Exception {
	        Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
	        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
	        hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
	        hints.put(EncodeHintType.MARGIN, 1);
	        BitMatrix bitMatrix = new MultiFormatWriter().encode(content,
	                BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE, hints);
	        int width = bitMatrix.getWidth();
	        int height = bitMatrix.getHeight();
	        BufferedImage image = new BufferedImage(width, height,
	                BufferedImage.TYPE_INT_RGB);
	        for (int x = 0; x < width; x++) {
	            for (int y = 0; y < height; y++) {
	                image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
	            }
	        }
	        //判断LOGO图片地址是否为空
	        if (imgPath == null || "".equals(imgPath)) {
	            return image;
	        }
	        // 插入LOGO图片
	        QRCodeUtil.insertImage(image, imgPath, needCompress);
	        return image;
	    }


		/**
		 * 插入LOGO
		 * @param source 二维码图片
		 * @param imgPath  LOGO图片地址
		 * @param needCompress  是否压缩
		 * @return
		 * @throws Exception
		 */
	    private static void insertImage(BufferedImage source,String imgPath,boolean needCompress) throws Exception {
			/**
			 * 1.通过本地路径创建文件对象
			 */
/*
            File file = new File(imgPath);
	        if (!file.exists()) {
	            System.err.println(""+imgPath+"该文件不存在！");
	            return;
	        }
	        Image src = ImageIO.read(file);
	*/
			/**
			 * 2.从阿里云拿到logo图片
			 */
			Image src = ImageIO.read(new URL(imgPath).openStream());

			int width = src.getWidth(null);
	        int height = src.getHeight(null);
	        if (needCompress) { // 压缩LOGO
	            if (width > WIDTH) {
	                width = WIDTH;
	            }
	            if (height > HEIGHT) {
	                height = HEIGHT;
	            }
	            Image image = src.getScaledInstance(width, height,
	                    Image.SCALE_SMOOTH);
	            BufferedImage tag = new BufferedImage(width, height,
	                    BufferedImage.TYPE_INT_RGB);
	            Graphics g = tag.getGraphics();
	            g.drawImage(image, 0, 0, null); // 绘制缩小后的图
	            g.dispose();
	            src = image;
	        }
	        // 插入LOGO图片
	        Graphics2D graph = source.createGraphics();
	        int x = (QRCODE_SIZE - width) / 2;
	        int y = (QRCODE_SIZE - height) / 2;
	        graph.drawImage(src, x, y, width, height, null);
	        Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6);
	        graph.setStroke(new BasicStroke(3f));
	        graph.draw(shape);
	        graph.dispose();
	    }

		/**
		 * 生成二维码(内嵌LOGO)
		 * @param content 内容
		 * @param imgPath LOGO地址
		 * @param destPath 存放目录
		 * @param needCompress 是否压缩LOGO
		 * @return
		 * @throws Exception
		 */
	    public static void encode(String content, String imgPath, String destPath, boolean needCompress) throws Exception {
	        BufferedImage image = QRCodeUtil.createImage(content,imgPath,needCompress);
			/**
			 * 1.上传到阿里云OSS
			 */
/*			OSSUtil ossUtil=OSSUtil.getInstance();
			ByteArrayOutputStream os = new ByteArrayOutputStream();
			ImageIO.write(image, FORMAT_NAME, os);
			InputStream is = new ByteArrayInputStream(os.toByteArray());

			boolean ioss=ossUtil.passFileStrem(destPath+".jpeg",is);
			String ossurl = null;
			if(ioss){
				ossurl=ossUtil.getImgUrl(destPath+".jpeg");
				log.info("成功:"+ossurl);
			}else {
				log.info("失败");
			}
			return ossurl;*/

			/**
			 * 2.写到本地
			 */
			mkdirs(destPath);
			String file = new Random().nextInt(99999999)+".jpg";
			ImageIO.write(image, FORMAT_NAME, new File(destPath+"/"+file));
	    }

		/**
		 * 当文件夹不存在时，mkdirs会自动创建多层目录，区别于mkdir．(mkdir如果父目录不存在则会抛出异常)
		 * @author lanyuan
		 * Email: mmm333zzz520@163.com
		 * @date 2013-12-11 上午10:16:36
		 * @param destPath 存放目录
		*/
	    public static void mkdirs(String destPath) {
	        File file =new File(destPath);
	        //当文件夹不存在时，mkdirs会自动创建多层目录，区别于mkdir．(mkdir如果父目录不存在则会抛出异常)
	        if (!file.exists() && !file.isDirectory()) {
	            file.mkdirs();
	        }
	    }

		/**
		 * 生成二维码(内嵌LOGO)
		 * @param content 内容
		 * @param imgPath LOGO地址
		 * @param destPath 存储地址
		 * @return
		 * @throws Exception
		 */
	    public static void encode(String content, String imgPath, String destPath)
	            throws Exception {
	        QRCodeUtil.encode(content,imgPath, destPath, false);
	    }

		/**
		 * 生成二维码
		 * @param content 内容
		 * @param destPath 存储地址
		 * @param needCompress 是否压缩LOGO
		 * @return
		 * @throws Exception
		 */
	    public static void encode(String content, String destPath,boolean needCompress) throws Exception {
	        QRCodeUtil.encode(content, null, destPath, needCompress);
	    }

		/**
		 * 生成二维码
		 * @param content 内容
		 * @param destPath 存储地址
		 * @return
		 * @throws Exception
		 */
	    public static void encode(String content, String destPath) throws Exception {
	        QRCodeUtil.encode(content, null, destPath, false);
	    }

		/**
		 * 生成二维码(内嵌LOGO)
		 * @param content 内容
		 * @param imgPath LOGO地址
		 * @param output 输出流
		 * @param needCompress 是否压缩LOGO
		 * @return
		 * @throws Exception
		 */
	    public static void encode(String content, String imgPath, OutputStream output, boolean needCompress) throws Exception {
	        BufferedImage image = QRCodeUtil.createImage(content, imgPath, needCompress);
	        ImageIO.write(image, FORMAT_NAME, output);
	    }

		/**
		 * 生成二维码
		 * @param content 内容
		 * @param output 输出流
		 * @return
		 * @throws Exception
		 */
	    public static void encode(String content, OutputStream output) throws Exception {
	        QRCodeUtil.encode(content, null, output, false);
	    }
		/**
		 * 解析二维码
		 * @param file 二维码图片
		 * @return
		 * @throws Exception
		 */
	    public static String decode(File file) throws Exception {
	        BufferedImage image;
	        image = ImageIO.read(file);
	        if (image == null) {
	            return null;
	        }
	        BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(image);
	        BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
	        Result result;
	        Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>();
	        hints.put(DecodeHintType.CHARACTER_SET, CHARSET);
	        result = new MultiFormatReader().decode(bitmap, hints);
	        String resultStr = result.getText();
	        return resultStr;
	    }

		/**
		 * 解析二维码
		 * @param path 二维码图片地址
		 * @return
		 * @throws Exception
		*/
	    public static String decode(String path) throws Exception {
	        return QRCodeUtil.decode(new File(path));
	    }

		/**
		 * 测试
		 * @param args
		 * @throws Exception
		 */
		public static void main(String[] args) throws Exception {
	//	        String text = "listener是监听程序的监听端口，而SID_LIST_LISTENER则指定监听程序要负责对哪些数据库进行监听";
	//      	String logo = "http://o8p0659zt.bkt.clouddn.com/1478836114936sHh4";
	//			String logo = "";
	//			String key= UUID.randomUUID().toString().replaceAll("-","");
	//			QRCodeUtil.encode(text,logo,"key",true);

			/**
			 * 解析二维码
			 */
	//			System.out.println(decode("D:/73706220.jpeg"));
			}

}
